package com.jiantong.admin.controller.report;

import com.google.common.collect.Maps;
import com.jiantong.admin.dto.CityAreaDto;
import com.jiantong.admin.model.PagingMz;
import com.jiantong.admin.util.ExportOrImportUtils;
import com.jiantong.user.model.*;
import com.jiantong.user.service.*;
import com.jiantong.web.core.enums.ExceptionCode;
import com.jiantong.work.enums.DocumentsDeleteFlag;
import com.jiantong.work.model.BreedReportsForm;
import com.jiantong.work.service.BreedReportsFormReadService;
import io.terminus.boot.rpc.common.annotation.RpcConsumer;
import io.terminus.common.model.Paging;
import io.terminus.common.model.Response;
import io.terminus.pampas.openplatform.exceptions.OPServerException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
 * Created by mz on 11/9/17.
 *
 */
@Slf4j
@Controller
public class BreedReportsFormController {

    @RpcConsumer
    private BreedReportsFormReadService breedReportsFormReadService;

    @RpcConsumer
    private UserReadService userReadService;
    @RpcConsumer
    private UserProfileReadService userProfileReadService;
    @RpcConsumer
    private GovernmentUserDutyReadService governmentUserDutyReadService;
    @RpcConsumer
    private BreedFactoryReadService breedFactoryReadService;

    @RpcConsumer
    private DeclareStationReadService declareStationReadService;

    @RpcConsumer
    private DepartmentExtendReadService departmentExtendReadService;


    @GetMapping("/djt/report/breedReportsForm")
    public String aa(Model model,HttpServletRequest request, HttpServletResponse response){

        Map loginUserMap = getarea(response, request);

        model.addAttribute("breedFactoryList",loginUserMap.get("breedFactorys"));
        model.addAttribute("username",loginUserMap.get("username"));
        model.addAttribute("cityAreaDtoList",loginUserMap.get("cityAreaDtoList"));
        model.addAttribute("declareStations",loginUserMap.get("declareStations"));
        return "/djt/report/breedReportsForm";
    }

    @GetMapping("/djt/report/breedReportsForm1")
    @ResponseBody
    public PagingMz<BreedReportsForm> aa(
                     @RequestParam(required = false) Integer page ,
                     @RequestParam(required = false) Integer rows ,
                     @RequestParam(required = false) Date start,
                     @RequestParam(required = false) Date end,
                     @RequestParam(required = false) String factoryIds,
                     @RequestParam(required = false) Long declareStationId,
                     HttpServletRequest httpServletRequest,
                     HttpServletResponse httpServletResponse
    ) throws IOException {
        page = page == null ? 1 : page;
        rows = rows == null ? 20:rows;
        Map<String , Object> criteria = Maps.newHashMap();

        if (start != null) {
            criteria.put("start", start);
        }
        if (end != null) {
            criteria.put("end", end);
        }
        if(declareStationId != null && declareStationId != -1) criteria.put("declareStationId",declareStationId);
        List<Long> breedFactoryIds = new ArrayList<>();

        String[] strings = factoryIds.split(",");
        for(String s : strings){
            breedFactoryIds.add(Long.parseLong(s));
        }
        criteria.put("breedFactoryIds",breedFactoryIds);

        Response<Paging<BreedReportsForm>> pagingResponse =
                breedReportsFormReadService.pagingBreedReportsFormForWeb(page,rows,criteria);
        if(!pagingResponse.isSuccess()){
            log.error("failed to paging.BreedReportsForm, cause : {}", pagingResponse.getError());
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),
                    pagingResponse.getError());
        }
        List<BreedReportsForm> list = pagingResponse.getResult().getData();
        Long total = pagingResponse.getResult().getTotal();

        for(BreedReportsForm breedReportsForm : list){

            Map<String , Object> receiveAddressMap = breedReportsForm.getReceiveAddressMap();

            if(receiveAddressMap == null || receiveAddressMap.isEmpty()){
                breedReportsForm.setReceiveAddressValue(breedReportsForm.getButcherFactoryName());
            }else {
                String province = (String) receiveAddressMap.getOrDefault("province","");
                String city = (String) receiveAddressMap.getOrDefault("city","");
                String region = (String) receiveAddressMap.getOrDefault("region","");
                String street = (String) receiveAddressMap.getOrDefault("street","");
                String butcher = (String) receiveAddressMap.getOrDefault("butcher","");
                breedReportsForm.setReceiveAddressValue(province + city + region + street + butcher);
            }
        }

        Long pageTotal = (total - 1) / rows + 1;
        return new PagingMz<>(pageTotal,total,page,list);
    }

    @GetMapping("/getDepartment")
    @ResponseBody
    public DepartmentExtend getDepartment(@RequestParam(required = false) Long declareStationId){

        Response<DepartmentExtend> response = departmentExtendReadService.findByDepartmentExtend(declareStationId,2);
        if(!response.isSuccess()){
            log.error("failed to find department by declareStationId");
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),response.getError());
        }
        return response.getResult();
    }

    @GetMapping("/getDeclareStation")
    @ResponseBody
    public DeclareStation getDeclareStation(@RequestParam(required = false) Long declareStationId){

        Response<DeclareStation> response = declareStationReadService.findById(declareStationId);
        if(!response.isSuccess()){
            log.error("failed to find DeclareStation by declareStationId");
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),response.getError());
        }
        return response.getResult();
    }

    @GetMapping("/getExcel/{start}/{end}/{breedType}/{breedFactoryIds}/{declareStationId}")
    public void listBreedReportsFormForWeb(@PathVariable(value = "start",required = false) Date start,
                                          @PathVariable(value = "end",required = false) Date end,
                                          @PathVariable(value = "breedType",required = false) Integer breedType,
                                          @PathVariable(value = "breedFactoryIds",required = false) List<Long> breedFactoryIds,
                                          @PathVariable(value = "declareStationId",required = false) Long declareStationId,
                                          HttpServletResponse response) throws IOException {
        Map<String , Object> map = Maps.newHashMap();

        map.put("start",start);
        map.put("end",end);

        if(breedType != -1){
            map.put("breedType",breedType);
        }
        if(declareStationId != -1){
            map.put("declareStationId",declareStationId);
        }

        if(breedFactoryIds != null && !breedFactoryIds.isEmpty()){
            map.put("breedFactoryIds",breedFactoryIds);
        }

        map.put("deleteFlag", DocumentsDeleteFlag.NORMAL.value());
        Response<List<BreedReportsForm>> response1 = breedReportsFormReadService.listBreedReportsFormForWeb(map);

        ExportOrImportUtils.dataExportDownload(response,buildTitles(),"产地检疫报表", buildDataMaps(response1.getResult()));
    }

    @GetMapping("/djt/report/formModel")
    public String getFormModel(){
        return "/djt/report/formModel";
    }

    @GetMapping("/UsergetExcel")
    @ResponseBody
    public int UserExportDownload(HttpServletResponse response) throws IOException {

        ExportOrImportUtils. UserExportDownload(response,UsetInfoTitles());
        return 0;
    }


    private List<LinkedHashMap<String , Object>> buildDataMaps(List<BreedReportsForm> list){
        List<LinkedHashMap<String , Object>> linkedHashMapList = new ArrayList<>();
        LinkedHashMap<String , Object> linkedHashMap = null;

        for(BreedReportsForm breedReportsForm : list){
            linkedHashMap = new LinkedHashMap<>();
//            linkedHashMap.put("id",breedReportsForm.getId());
            linkedHashMap.put("owner",breedReportsForm.getOwner());
            linkedHashMap.put("reportNumber",breedReportsForm.getReportNumber());
            Integer breedType = breedReportsForm.getBreedType();
            String breedTypeString = "其他";
            switch (breedType){
                case 1:
                    breedTypeString = "猪";
                    break;
                case 2:
                    breedTypeString = "牛";
                    break;
                case 3:
                    breedTypeString = "羊";
                    break;
                case 4:
                    breedTypeString = "家禽";
                    break;
                case 5:
                    breedTypeString = "其他";
                    break;
                default:
                    break;
            }
            linkedHashMap.put("breedType",breedTypeString);
            linkedHashMap.put("quantity",breedReportsForm.getQuantity());
            linkedHashMap.put("applyReportName",breedReportsForm.getApplyReportName());
            linkedHashMap.put("qualifiedQuantity",breedReportsForm.getQualifiedQuantity());
            linkedHashMap.put("quarantineCertNumber",breedReportsForm.getQuarantineCertNumber());
            linkedHashMap.put("unqualifiedQuantity",breedReportsForm.getUnqualifiedQuantity());
            linkedHashMap.put("harmlessNumber",breedReportsForm.getHarmlessNumber());
            Map<String , Object> receiveAddressMap = breedReportsForm.getReceiveAddressMap();

            if(receiveAddressMap == null || receiveAddressMap.isEmpty()){
                breedReportsForm.setReceiveAddressValue(breedReportsForm.getButcherFactoryName());
            }else {
                String province = (String) receiveAddressMap.getOrDefault("province","");
                String city = (String) receiveAddressMap.getOrDefault("city","");
                String region = (String) receiveAddressMap.getOrDefault("region","");
                String street = (String) receiveAddressMap.getOrDefault("street","");
                String butcher = (String) receiveAddressMap.getOrDefault("butcher","");
                breedReportsForm.setReceiveAddressValue(province + city + region + street + butcher);
            }
            linkedHashMap.put("receiveAddressValue",breedReportsForm.getReceiveAddressValue());
            linkedHashMap.put("transportNumber",breedReportsForm.getTransportNumber());
            linkedHashMap.put("vetUserName",breedReportsForm.getVetUserName());
            linkedHashMap.put("remark",breedReportsForm.getRemark());

            linkedHashMapList.add(linkedHashMap);
        }

        return linkedHashMapList;
    }

    private List<String> buildTitles(){
        List<String> list = new ArrayList<>();

        list.add("货主");
        list.add("申报编号");
        list.add("动物种类");
        list.add("检疫数量");
        list.add("检疫地点");
        list.add("合格数");
        list.add("《动物检疫合格证》编号");
        list.add("不合格数");
        list.add("《检疫处理通知单》编号");
        list.add("目的地");
        list.add("运载工具牌号");
        list.add("官方兽医姓名");
        list.add("备注");

        return list;
    }
    private List<String> UsetInfoTitles(){
        List<String> list = new ArrayList<>();
        list.add("用户名字");
        list.add("用户邮箱");
        list.add("用户手机号");
        list.add("用户密码");
        list.add("地区等级（数字）");
        list.add("性别（0,1,2）");
        list.add("省ID");
        list.add("省名字");
        list.add("市ID");
        list.add("市名字");
        list.add("县ID");
        list.add("县名字");
        list.add("镇ID");
        list.add("镇名字");
        list.add("村ID");
        list.add("村名字");
        list.add("机构名字");
        list.add("机构ID");
        list.add("机构类型（1,2,3,4,5）");
        list.add("机构用户角色");
        list.add("APP角色（数字）");
        list.add("部门ID");
        list.add("部门名字");
        list.add("部门类型（1,2,3）");

        return list;
    }
    public Map getarea(HttpServletResponse response, HttpServletRequest request) {
        List<String> list = new ArrayList<>();
        list.add("province");
        list.add("city");
        list.add("region");
        list.add("street");
        list.add("village");
        Cookie[] cookies = null;
        cookies = request.getCookies();
        String name = "";
        Map map = new HashMap();
        for (Cookie cookie : cookies) {

            if (cookie.getName().equals("djtid")) {
                String id = cookie.getValue();
                int Id = Integer.parseInt(id);
                Response<User> userResponse = userReadService.findById(Integer.toUnsignedLong(Id));
                name = userResponse.getResult().getName();
                map.put("username", name);
                switch (userResponse.getResult().getAreaLevel()) {
                    case 1:
                        UserProfile userProfile = userProfileReadService.findUserProfileById(userResponse.getResult().getId()).getResult();
                        String Province = userProfile.getProvince();
                        Map map6 = new HashMap();
                        map6.put("province", Province);
                        List<BreedFactory> breedFactoryList = (List<BreedFactory>) breedFactoryReadService.findByArea(map6).getResult();
                        //获取所有省下城市

                        Map map1 = new HashMap();
                        map1.put("area1", list.get(1));
                        map1.put("area2", list.get(0));
                        map1.put("area3", Province);
                        List<String> citys = breedFactoryReadService.serachAllregion1(map1);
                        //获取城市下所有区
                        List<CityAreaDto> cityAreaDtoList = new ArrayList<>();
                        for (String city : citys) {
                            CityAreaDto cityAreaDto = new CityAreaDto();
                            Map map2 = new HashMap();
                            map2.put("area1", list.get(2));
                            map2.put("area2", list.get(1));
                            map2.put("area3", city);
                            List<String> regions = breedFactoryReadService.serachAllregion1(map2);
                            cityAreaDto.setCity(city);
                            cityAreaDto.setRegions(regions);
                            cityAreaDtoList.add(cityAreaDto);

                        }
                        map.put("userProfile",userProfile);
                        map.put("cityAreaDtoList", cityAreaDtoList);
                        map.put("breedFactorys", breedFactoryList);
                        //switch break;
                        break;
                    case 2:
                        UserProfile userProfile2 = userProfileReadService.findUserProfileById(userResponse.getResult().getId()).getResult();
                        String city1 = userProfile2.getCity();
                        Map map7 = new HashMap();
                        map7.put("city", city1);
                        List<BreedFactory> breedFactoryList1 = (List<BreedFactory>) breedFactoryReadService.findByArea(map7).getResult();
                        //获取所有省下城市

                        Map map21 = new HashMap();
                        map21.put("area1", list.get(2));
                        map21.put("area2", list.get(1));
                        map21.put("area3", city1);
                        List<String> citys2 = breedFactoryReadService.serachAllregion1(map21);
                        //获取城市下所有区
                        List<CityAreaDto> cityAreaDtoList1 = new ArrayList<>();
                        for (String city : citys2) {
                            CityAreaDto cityAreaDto = new CityAreaDto();
                            Map map2 = new HashMap();
                            map2.put("area1", list.get(3));
                            map2.put("area2", list.get(2));
                            map2.put("area3", city);
                            List<String> regions = breedFactoryReadService.serachAllregion1(map2);
                            cityAreaDto.setCity(city);
                            cityAreaDto.setRegions(regions);
                            cityAreaDtoList1.add(cityAreaDto);

                        }
                        map.put("userProfile",userProfile2);
                        map.put("cityAreaDtoList", cityAreaDtoList1);
                        map.put("breedFactorys", breedFactoryList1);
                        //switch break;
                        break;
                    case 3://区
                        UserProfile userProfile3 = userProfileReadService.findUserProfileById(userResponse.getResult().getId()).getResult();
                        String region = userProfile3.getRegion();
                        Map map36 = new HashMap();
                        map36.put("region", region);
                        List<BreedFactory> breedFactoryList3 = (List<BreedFactory>) breedFactoryReadService.findByArea(map36).getResult();
                        //获取所有区下城市镇

                        Map map31 = new HashMap();
                        map31.put("area1", list.get(3));
                        map31.put("area2", list.get(2));
                        map31.put("area3", region);
                        List<String> citys3 = breedFactoryReadService.serachAllregion1(map31);
                        //获取对应镇 对应村
                        List<CityAreaDto> cityAreaDtoList3 = new ArrayList<>();
                        for (String city : citys3) {
                            CityAreaDto cityAreaDto = new CityAreaDto();
                            Map map2 = new HashMap();
                            map2.put("area1", list.get(4));
                            map2.put("area2", list.get(3));
                            map2.put("area3", city);
                            List<String> regions = breedFactoryReadService.serachAllregion1(map2);
                            cityAreaDto.setCity(city);
                            cityAreaDto.setRegions(regions);
                            cityAreaDtoList3.add(cityAreaDto);

                        }
                        map.put("userProfile",userProfile3);
                        map.put("cityAreaDtoList", cityAreaDtoList3);
                        map.put("breedFactorys", breedFactoryList3);
                        //switch break;
                        break;
                    case 4://镇
                        UserProfile userProfile4 = userProfileReadService.findUserProfileById(userResponse.getResult().getId()).getResult();
                        String street = userProfile4.getStreet();
                        Map map46 = new HashMap();
                        map46.put("street", street);
                        List<BreedFactory> breedFactoryList4 = (List<BreedFactory>) breedFactoryReadService.findByArea(map46).getResult();
                        //获取所有镇下所有村

                        Map map41 = new HashMap();
                        map41.put("area1", list.get(4));
                        map41.put("area2", list.get(3));
                        map41.put("area3", street);
                        List<String> citys4 = breedFactoryReadService.serachAllregion1(map41);//所有村

                        List<CityAreaDto> cityAreaDtoList4 = new ArrayList<>();

                        CityAreaDto cityAreaDto = new CityAreaDto();

                        cityAreaDto.setCity(street);
                        cityAreaDto.setRegions(citys4);
                        cityAreaDtoList4.add(cityAreaDto);

                        map.put("userProfile",userProfile4);
                        map.put("cityAreaDtoList", cityAreaDtoList4);
                        map.put("breedFactorys", breedFactoryList4);
                        //switch break;
                        break;
                    case 5://村
                        UserProfile userProfile99 = userProfileReadService.findUserProfileById(userResponse.getResult().getId()).getResult();
                        List<GovernmentUserDuty> governmentUserDutyList = governmentUserDutyReadService.findGovernmentUserDutiesByUserId(userResponse.getResult().getId(), null).getResult();
                        List<Long> longlist = new ArrayList<>();
                        for (GovernmentUserDuty governmentUserDuty : governmentUserDutyList) {
                            longlist.add(governmentUserDuty.getFactoryOrPointId());
                        }
                        List<String> villages = new ArrayList<>();
                        List<BreedFactory> breedFactoryList2 = breedFactoryReadService.findBreedFactoryDtoByIds(longlist).getResult();
                        for (BreedFactory breedFactory : breedFactoryList2) {
                            villages.add(breedFactory.getVillage());

                        }

                        List<String> listWithoutDup = new ArrayList<String>(new HashSet<String>(villages));


                        List<CityAreaDto> cityAreaDtoList5 = new ArrayList<>();

                        CityAreaDto cityAreaDto1 = new CityAreaDto();
                        cityAreaDto1.setCity(" ");

                        // cityAreaDto1.setCity(village);
                        cityAreaDto1.setRegions(listWithoutDup);

                        cityAreaDtoList5.add(cityAreaDto1);

                        map.put("userProfile",userProfile99);
                        map.put("cityAreaDtoList", cityAreaDtoList5);
                        map.put("breedFactorys", breedFactoryList2);
                        //switch break;
                        break;
                }

                Response<List<GovernmentUserDuty>> response1 = governmentUserDutyReadService.findGovernmentUserDutiesByUserId(userResponse.getResult().getId(),null);
                if(!response1.isSuccess()){
                    log.error("failed to find user info ");
                    throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),response1.getError());
                }
                List<DeclareStation> declareStations = new ArrayList<>();
                List<Long> declareStationIds = new ArrayList<>();
                for(GovernmentUserDuty governmentUserDuty : response1.getResult()){
                    if(governmentUserDuty.getFactoryOrPointType() == 2){
                        declareStationIds.add(governmentUserDuty.getFactoryOrPointId());
                    }
                }
                Response<List<DeclareStation>> response2 = declareStationReadService.findByIds(declareStationIds);
                if(!response2.isSuccess()){
                    log.error("failed to find ");
                    throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),response2.getError());
                }
                declareStations = response2.getResult();
                map.put("declareStations",declareStations);
                map.put("declareStationIds",declareStationIds);
                break;
            }
        }

        return map;
    }
}
